package com.chen.blue.service.system.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chen.blue.converter.system.DataScopeDeptUserConverter;
import com.chen.blue.converter.system.UserRoleConverter;
import com.chen.blue.domain.delete.system.DataScopeUserDeptDelete;
import com.chen.blue.domain.dto.system.DataScopeUserDeptDto;
import com.chen.blue.domain.dto.system.update.DataScopeUserDeptDtoEdit;
import com.chen.blue.domain.dto.system.update.UserRoleDtoEdit;
import com.chen.blue.domain.model.system.DataScopeUserDeptModel;
import com.chen.blue.domain.model.system.DeptModel;
import com.chen.blue.domain.model.system.MenuModel;
import com.chen.blue.domain.model.system.MenuRoleModel;
import com.chen.blue.domain.query.system.DeptQuery;
import com.chen.blue.domain.vo.system.DataScopeUserDeptVo;
import com.chen.blue.domain.vo.system.DeptVo;
import com.chen.blue.domain.vo.system.MenuRoleVo;
import com.chen.blue.domain.vo.system.MenuVo;
import com.chen.blue.exception.e.DtoNullException;
import com.chen.blue.mapper.system.DataScopeUserDeptMapper;
import com.chen.blue.result.DataResult;
import com.chen.blue.service.candidate.CandidateInfoService;
import com.chen.blue.service.system.IDataScopeUserDeptService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.blue.service.system.IDeptService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author CLT
 * @since 2024-05-11
 */
@Service("iDataScopeUserDeptService")
public class IDataScopeUserDeptServiceImpl extends ServiceImpl<DataScopeUserDeptMapper, DataScopeUserDeptModel> implements IDataScopeUserDeptService {

    @Resource
    private IDeptService iDeptService;

    @Override
    public boolean addDataScopeUserDept(List<DataScopeUserDeptDto> dataScopeUserDeptDtoList) throws DtoNullException {

        if (Objects.isNull(dataScopeUserDeptDtoList)) {
            throw new DtoNullException("参数为空");
        }

        CandidateInfoService.setCreator(dataScopeUserDeptDtoList);

        return super.saveBatch(DataScopeDeptUserConverter.dtoListToModelList(dataScopeUserDeptDtoList));

    }

    @Override
    public boolean deleteDataScopeUserDept(DataScopeUserDeptDelete dataScopeUserDeptDelete) throws DtoNullException {

        if (Objects.isNull(dataScopeUserDeptDelete) && Objects.isNull(dataScopeUserDeptDelete.getUserId())) {
            throw new DtoNullException("参数为空");
        }

        Map<String, Object> wrap = new HashMap<>();
        wrap.put("user_id", dataScopeUserDeptDelete.getUserId());

        return Objects.nonNull(dataScopeUserDeptDelete.getUserIds()) ? super.removeByIds(dataScopeUserDeptDelete.getUserIds()) : super.removeByMap(wrap);

    }

    @Override
    public boolean updateDataScopeUserDept(List<DataScopeUserDeptDtoEdit> dataScopeUserDeptDtoEditList) throws DtoNullException {

        if (Objects.isNull(dataScopeUserDeptDtoEditList) || dataScopeUserDeptDtoEditList.isEmpty())
            return false;

        // 将指定的用户的部门全部删除
        DataScopeUserDeptDtoEdit dataScopeUserDeptDtoEdit = dataScopeUserDeptDtoEditList.get(0);
        Long userId = dataScopeUserDeptDtoEdit.getUserId();
        Map<String, Object> wrap = new HashMap<>();
        wrap.put("user_id", userId);
        super.removeByMap(wrap);

        CandidateInfoService.setCreator(dataScopeUserDeptDtoEditList);

        // 重新添加部门
        return super.saveBatch(DataScopeDeptUserConverter.editDtoListToModelList(dataScopeUserDeptDtoEditList));

    }

    @Override
    public DataResult<Map<String, Object>> queryDataScopeUserDeptVoById(Long userId) throws DtoNullException {

        if (Objects.isNull(userId)) {
            throw new DtoNullException("参数为空");
        }

        LambdaQueryWrapper<DataScopeUserDeptModel> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DataScopeUserDeptModel::getUserId, userId);
        Set<Long> deptIds = super.list(wrapper).stream().map(DataScopeUserDeptModel::getDeptId).collect(Collectors.toSet());

        DataResult<List<DeptVo>> deptVoDataResult = iDeptService.queryDept(new DeptQuery(), true);

        DataResult<Map<String, Object>> dataResult = new DataResult<>();
        dataResult.setData(converter(deptVoDataResult, deptIds));

        return dataResult;

    }


    /**
     * 转换数据，避免暴露太多数据
     *
     * @param dataResult
     * @return
     */
    protected Map<String, Object> converter(DataResult<List<DeptVo>> dataResult, Set<Long> deptIds) {

        Map<String, Object> result = null;

        List<DeptVo> deptVoList = dataResult.getResult();

        if (!(Objects.nonNull(deptVoList) && !deptVoList.isEmpty())) {
            return null;
        }

        result = new HashMap<>();
        result.put("checkedKeys", deptIds);

        List<DataScopeUserDeptVo> dataScopeUserDeptVoList = deptVoList.stream().map(obj -> {
            DataScopeUserDeptVo dataScopeUserDeptVo = new DataScopeUserDeptVo();
            dataScopeUserDeptVo.setId(obj.getId());
            dataScopeUserDeptVo.setLabel(obj.getName());
            dataScopeUserDeptVo.setName(obj.getName());
            if (Objects.nonNull(obj.getChildren())) {
                dataScopeUserDeptVo.setChildren(setChildrenVo(obj.getChildren()));
            }
            return dataScopeUserDeptVo;
        }).collect(Collectors.toList());

        result.put("depts", dataScopeUserDeptVoList);

        return result;

    }

    protected List<DataScopeUserDeptVo> setChildrenVo(List<DeptVo> list) {

        return list.stream().map(obj -> {
            DataScopeUserDeptVo dataScopeUserDeptVo = new DataScopeUserDeptVo();
            dataScopeUserDeptVo.setId(obj.getId());
            dataScopeUserDeptVo.setLabel(obj.getName());
            dataScopeUserDeptVo.setName(obj.getName());
            if (Objects.nonNull(obj.getChildren())) {
                dataScopeUserDeptVo.setChildren(setChildrenVo(obj.getChildren()));
            }
            return dataScopeUserDeptVo;
        }).collect(Collectors.toList());

    }

}
